﻿using System;
using System.Collections;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Caching;
using System.Collections.Generic;

namespace Job.Core.Web
{
    #region Cache
    /// <summary>
    /// 缓存辅助操作封装。
    /// </summary>
    public static class Cache
    {
        #region Methods

        /// <summary>
        /// 从 Cache 对象检索指定项。
        /// </summary>
        /// <param name="key">要检索的缓存项的标识符。</param>
        /// <returns>检索到的缓存项，未找到该键时为 null 引用（在 Visual Basic 中为 Nothing）。</returns>
        public static object Get(string key)
        {
            return HttpRuntime.Cache.Get(key);
        }

        /// <summary>
        /// 以强类型方式从 Cache 对象检索指定项。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">要检索的缓存项的标识符。</param>
        /// <returns>检索到的缓存项，未找到该键时为 T 的默认值。</returns>
        public static T Get<T>(string key)
        {
            object obj = Get(key);

            if (obj != null)
                return (T)obj;

            return default(T);
        }

        /// <summary>
        /// 从 Cache 对象检索正则表达式匹配的缓存项。
        /// </summary>
        /// <param name="pattern">要匹配的模式。</param>       
        /// <param name="ignoreCase">匹配是否忽略大小写。</param>
        /// <returns>匹配的缓存项实例序列。</returns>
        public static IList<object> Get(string pattern, bool ignoreCase)
        {
            Regex regex;

            if (ignoreCase)
                regex = new Regex(pattern, RegexOptions.IgnoreCase);
            else
                regex = new Regex(pattern);

            IList<object> list = new List<object>();

            foreach (DictionaryEntry entry in HttpRuntime.Cache)
            {
                string key = entry.Key.ToString();
                if (regex.IsMatch(key))
                    list.Add(entry.Value);
            }

            return list;
        }

        /// <summary>
        /// 以强类型方式从 Cache 对象检索正则表达式匹配的缓存项。
        /// </summary>
        /// <param name="pattern">要匹配的模式。</param>       
        /// <param name="ignoreCase">匹配是否忽略大小写。</param>
        /// <returns>匹配的缓存项实例序列。</returns>
        public static IList<T> Get<T>(string pattern, bool ignoreCase)
        {
            IList<object> oList = Get(pattern, ignoreCase);
            IList<T> tList = new List<T>();

            foreach(object obj in oList)
            {
                if (obj is T)
                    tList.Add((T)obj);
            }

            return tList;
        }

        /// <summary>
        /// 向 Cache 对象中插入对象，后者具有依赖项、过期和优先级策略以及一个委托（可用于在从 Cache 移除插入项时通知应用程序）。
        /// </summary>
        /// <param name="key">用于引用该对象的缓存键。</param>
        /// <param name="value">要插入缓存中的对象。</param>
        /// <param name="dependencies">所插入对象的文件依赖项或缓存键依赖项。当任何依赖项更改时，该对象即无效，并从缓存中移除。如果没有依赖项，则此参数包含 null 引用（在 Visual Basic 中为 Nothing）。</param>
        /// <param name="absoluteExpiration">所插入对象将过期并被从缓存中移除的时间。若要避免可能出现的本地时间方面的问题（如从标准时间更改为夏时制），请对此参数值使用 UtcNow，不要使用 Now。如果使用绝对过期，则 slidingExpiration 参数必须为 NoSlidingExpiration。</param>
        /// <param name="slidingExpiration">最后一次访问所插入对象时与该对象过期时之间的时间间隔。如果该值等效于 20 分钟，则对象在最后一次被访问 20 分钟之后将过期并被从缓存中移除。如果使用可调过期，则 absoluteExpiration 参数必须为 NoAbsoluteExpiration。</param>
        /// <param name="priority">该对象相对于缓存中存储的其他项的成本，由 CacheItemPriority 枚举表示。该值由缓存在退出对象时使用；具有较低成本的对象在具有较高成本的对象之前被从缓存移除。</param>
        /// <param name="onRemoveCallback">在从缓存中移除对象时将调用的委托（如果提供）。当从缓存中删除应用程序的对象时，可使用它来通知应用程序。</param>
        public static void Insert(string key, Object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback)
        {
            HttpRuntime.Cache.Insert(key, value, dependencies, absoluteExpiration, slidingExpiration, priority, onRemoveCallback);
        }

        /// <summary>
        /// 向 Cache 中插入具有依赖项和过期策略的对象。
        /// </summary>
        /// <param name="key">用于引用该对象的缓存键。</param>
        /// <param name="value">要插入缓存中的对象。</param>
        /// <param name="dependencies">所插入对象的文件依赖项或缓存键依赖项。当任何依赖项更改时，该对象即无效，并从缓存中移除。如果没有依赖项，则此参数包含 null 引用（在 Visual Basic 中为 Nothing）。</param>
        /// <param name="absoluteExpiration">所插入对象将过期并被从缓存中移除的时间。若要避免可能出现的本地时间方面的问题（如从标准时间更改为夏时制），请对此参数值使用 UtcNow，不要使用 Now。如果使用绝对过期，则 slidingExpiration 参数必须为 NoSlidingExpiration。</param>
        /// <param name="slidingExpiration">最后一次访问所插入对象时与该对象过期时之间的时间间隔。如果该值等效于 20 分钟，则对象在最后一次被访问 20 分钟之后将过期并被从缓存中移除。如果使用可调过期，则 absoluteExpiration 参数必须为 NoAbsoluteExpiration。</param>
        public static void Insert(string key, Object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration)
        {
            HttpRuntime.Cache.Insert(key, value, dependencies, absoluteExpiration, slidingExpiration);
        }


        /// <summary>
        /// 向 Cache 中插入具有依赖项和过期策略的对象。
        /// </summary>
        /// <param name="key">用于引用该对象的缓存键。</param>
        /// <param name="value">要插入缓存中的对象。</param>
        /// <param name="absoluteExpiration">所插入对象将过期并被从缓存中移除的时间。若要避免可能出现的本地时间方面的问题（如从标准时间更改为夏时制），请对此参数值使用 UtcNow，不要使用 Now。如果使用绝对过期，则 slidingExpiration 参数必须为 NoSlidingExpiration。</param>
        public static void Insert(string key, Object value, DateTime absoluteExpiration)
        {
            HttpRuntime.Cache.Insert(key, value, null, absoluteExpiration, TimeSpan.Zero);
        }

        /// <summary>
        /// 向 Cache 中插入具有依赖项和过期策略的对象。
        /// </summary>
        /// <param name="key">用于引用该对象的缓存键。</param>
        /// <param name="value">要插入缓存中的对象。</param>
        /// <param name="dependencies">所插入对象的文件依赖项或缓存键依赖项。当任何依赖项更改时，该对象即无效，并从缓存中移除。如果没有依赖项，则此参数包含 null 引用（在 Visual Basic 中为 Nothing）。</param>
        public static void Insert(string key, Object value, CacheDependency dependencies)
        {
            HttpRuntime.Cache.Insert(key, value, dependencies);
        }

        /// <summary>
        /// 向 Cache 对象插入项，该项带有一个缓存键引用其位置，并使用 CacheItemPriority 枚举提供的默认值。
        /// </summary>
        /// <param name="key">用于引用该项的缓存键。</param>
        /// <param name="value">要插入缓存中的对象。</param>
        /// <remarks>此方法将覆盖其键与 key 参数相匹配的现有缓存项。使用 Insert 方法的此重载添加到缓存中的对象被插入，该对象没有文件或缓存依赖项，其优先级为 Default，可调过期值为 NoSlidingExpiration，绝对过期值为 NoAbsoluteExpiration。</remarks>
        public static void Insert(string key, object value)
        {
            HttpRuntime.Cache.Insert(key, value);
        }

        /// <summary>
        /// 移除应用程序缓存。
        /// </summary>
        /// <param name="key">缓存键。</param>
        public static void Remove(string key)
        {
            if (HttpRuntime.Cache[key] != null)
            {
                HttpRuntime.Cache.Remove(key);
            }
        }

        /// <summary>
        /// 移除以指定正则表达式匹配的缓存项。
        /// </summary>
        /// <param name="pattern">要匹配的模式。</param>       
        /// <param name="ignoreCase">匹配是否忽略大小写。</param>
        public static void Remove(string pattern, bool ignoreCase)
        {
            Regex regex;

            if (ignoreCase)
                regex = new Regex(pattern, RegexOptions.IgnoreCase);
            else
                regex = new Regex(pattern);

            foreach (DictionaryEntry entry in HttpRuntime.Cache)
            {
                string key = entry.Key.ToString();
                if (regex.IsMatch(key))
                    HttpRuntime.Cache.Remove(key);
            }
        }

        /// <summary>
        /// 清除 Web 应用程序所有缓存。
        /// </summary>
        public static void Clear()
        {
            HttpRuntime.Close();
        }

        #endregion



        public static System.Web.Caching.CacheDependency GetCacheDependency(string filename)
        {
            System.Web.Caching.CacheDependency cdd = new System.Web.Caching.CacheDependency(filename);
            return cdd;
        }

    }
    #endregion

}